/**
 * 
 */
package org.wolf.core.schema;

import java.io.IOException;
import java.io.Reader;

import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.TokenStream;
import org.apache.lucene.analysis.Tokenizer;
import org.apache.lucene.analysis.tokenattributes.CharTermAttribute;
import org.apache.lucene.document.Fieldable;

/**
 * @author 何小锋
 * 
 */
public class BoolField extends FieldType {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	protected final static char[] TRUE_TOKEN = { 'T' };
	protected final static char[] FALSE_TOKEN = { 'F' };

	protected final static Analyzer boolAnalyzer = new BoolAnalyzer();

	@Override
	public void setTokenized(boolean tokenized) {
	}

	@Override
	public Analyzer getAnalyzer() {
		return boolAnalyzer;
	}

	@Override
	public void setAnalyzer(Analyzer analyzer) {
	}

	@Override
	public Analyzer getQueryAnalyzer() {
		return boolAnalyzer;
	}

	@Override
	public void setQueryAnalyzer(Analyzer queryAnalyzer) {
	}

	@Override
	public String toInternal(Object value) {
		if (value == null)
			return "F";
		if (value instanceof Boolean)
			return ((Boolean) value) ? "T" : "F";
		String val = value.toString();
		char ch = !val.isEmpty() ? val.charAt(0) : 0;
		return (ch == '1' || ch == 't' || ch == 'T') ? "T" : "F";
	}

	@Override
	public Object toExternal(Fieldable f) {
		String value = f.stringValue();
		if (value == null)
			return Boolean.FALSE;
		return 'T' == value.charAt(0) ? Boolean.TRUE : Boolean.FALSE;
	}

	protected final static class BoolAnalyzer extends Analyzer {

		@Override
		public TokenStream tokenStream(String fieldName, Reader reader) {
			Tokenizer tokenizer = new Tokenizer(reader) {
				final CharTermAttribute termAtt = addAttribute(CharTermAttribute.class);
				boolean done = false;

				@Override
				public void reset(Reader input) throws IOException {
					super.reset(input);
					done = false;
				}

				@Override
				public boolean incrementToken() throws IOException {
					clearAttributes();
					if (done)
						return false;
					done = true;
					int ch = input.read();
					if (ch == -1)
						return false;
					termAtt.copyBuffer(
							((ch == 't' || ch == 'T' || ch == '1') ? TRUE_TOKEN
									: FALSE_TOKEN), 0, 1);
					return true;
				}
			};
			return tokenizer;
		}
	};

}
